/*mypipe.c*/
#include<unistd.h>
#include<fcntl.h>
#include<stdio.h>
#include<sys/types.h>
#include <stdlib.h>

void main() {
    int pid, mypipe[2];

    // 创建一个管道
    // mypipe[0] 是管道的读端，mypipe[1] 是管道的写端
    pipe(mypipe);

    // 创建一个子进程
    pid = fork();

    // 检查 fork 是否失败
    if (pid < 0) {
        // 输出错误信息
        perror("create process failed\n");
        // 终止程序
        exit(0);
    }

    if (pid == 0) {  // 子进程代码
        // 关闭管道的写端，因为子进程只需要从管道读取数据
        close(mypipe[1]);

        // 将标准输入（文件描述符 0）重定向到管道的读端
        // 这样，子进程从标准输入读取的数据实际上是从管道读取的
        dup2(mypipe[0], 0);

        // 关闭管道的读端，因为已经完成了重定向
        close(mypipe[0]);

        // 让子进程休眠 1 秒，确保父进程有足够的时间向管道写入数据
        sleep(1);

        // 执行 grep 命令，过滤包含 "init" 的行
        // execlp 函数会用新的程序替换当前进程的映像
        execlp("grep", "grep", "init", NULL);
    }
    else {  // 父进程代码
        // 关闭管道的读端，因为父进程只需要向管道写入数据
        close(mypipe[0]);

        // 将标准输出（文件描述符 1）重定向到管道的写端
        // 这样，父进程向标准输出写入的数据实际上是写入到管道的
        dup2(mypipe[1], 1);

        // 关闭管道的写端，因为已经完成了重定向
        close(mypipe[1]);

        // 执行 ps aux 命令，将进程信息输出到管道
        // execlp 函数会用新的程序替换当前进程的映像
        execlp("ps", "ps", "aux", NULL);
    }
}